home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48_1 / polyfit1 < prev    next >
Internet Message Format  |  1995-03-31  |  12KB

  1. Path: seq!spell
  2. From: David F. Kurth <dfk@hp-lsd.cos.hp.com>
  3. Subject:  v01i011:  polyfit10 - Polyfit v1.0: produce polynomial given N data points, Part01/01
  4. Newsgroups: comp.sources.hp48
  5. Followup-To: comp.sys.hp48
  6. Approved: spell@seq.uncwil.edu
  7.  
  8. Checksum: 3154341908 (verify with brik -cv)
  9.  
  10. Submitted-by: David F. Kurth <dfk@hp-lsd.cos.hp.com>
  11. Posting-number: Volume 1, Issue 11
  12. Archive-name: polyfit10/part01
  13.  
  14. BEGIN_DOC polyfit.doc
  15. I've always thought there should be a good use for a program like this,
  16. but I still haven't found it.  It was a good challenge to program the
  17. algorithm, and maybe someone else can find a good use for it.
  18.  
  19. POLYFIT produces the coefficients of an N-1 degree polynomial given
  20. N data points that lie on the curve of that polynomial.
  21. For example, consider the following table of data points:
  22.  
  23.    X     Y
  24. -----------
  25.   -2     1
  26.   -1    -1
  27.    0     1
  28.    1    -1
  29.    2     1
  30.  
  31. There are 5 data points, and the Y value a very symmetric.  POLYFIT
  32. produces the following polynomial:
  33.  
  34.   f(x) = 2/3*x^4 + 0*x^3 - 8/3*x^2 + 0*x^1 + 1*x^0
  35.  
  36. If you plot this with an X range between -2 and 2, you will see the
  37. curve "oscillate" between +1 and -1 as it hits all five data points.
  38.  
  39. POLYFIT is not a least square's type curve fit program.  There is no
  40. minimization of errors.  The polynomial coefficients found by POLYFIT
  41. will exactly hit the given data points (to within the accuracy of the 
  42. calculator).
  43.  
  44. Using POLYFIT
  45. Enter the following code into your calculator.  After loading, enter
  46. the new directory if not already there.  Push the CST key load the
  47. custom menu which should reveal the following keys:
  48.  
  49.   POLY - Executes the main program which takes the input array
  50.          of X-Y points from the stack and produces the K array of 
  51.          polymonial coefficients.
  52.   VEIW - Displays the coefficients of the resulting polynomial.
  53.   FX   - Calculates f(x) using level 1 of the stack for x.
  54.   X-Y  - Recalls the input data points to the stack for editing
  55.          or viewing.
  56.  
  57. To begin, you must first enter the input data points array.  This
  58. is easiest to do by using the Matrix Writer (Right-shift ENTER).
  59. Enter your first X-Y pair of points, then push the down arrow
  60. which informs the calculator that the array is only 2 elements wide.
  61. Continue entering the rest of your points until done.  Then just
  62. push ENTER to return the array to the stack.  Now push POLY to
  63. calculate the coefficients.
  64.  
  65. The display should produce "DOING L:" which can be ignored (the
  66. program calculates a triangular array of difference values used
  67. for the rest of the computations).  After this, the Ki coefficient
  68. values are calculated and briefly displayed.
  69.  
  70. When done, the K values can be displayed again by using the VIEW
  71. key.  Output values can be calculated by entering an X value on
  72. the stack and pressing the FX key.  Plotting the equation can
  73. be done by pressing Left-shift PLOT, PLOTR, and then AUTO.
  74.  
  75. For a small number of data points, the calculations are fairly
  76. quick.  For each additional data point entered, calculation time
  77. roughly doubles.  I've calculated 15 data points, but it took the
  78. calculator about 7.5 hours to finish.  However, with sufficient
  79. memory and batteries, have at it.
  80.  
  81. Dave Kurth
  82. dfk@hp-lsd.cos.hp.com
  83.  
  84. END_DOC
  85.  
  86. BYTES: #B610h 2267.5
  87.  
  88. BEGIN_RPL polyfit
  89. %%HP: T(3)A(D)F(.);
  90. DIR
  91. POLY
  92. @ This program takes an array of N X-Y values from the stack @
  93. @ and calculates the coefficients of an N-1 polynomial that @
  94. @ intersect with all N input points.  The N X-Y values are most @
  95. @ easily entered using the Matrix Writer Application. @
  96. @@
  97. @ Directory @
  98. @ Checksum # B610h
  99. @ Bytes    2267.5
  100. @@
  101. \<< IF DEPTH                            @ Check for an object on stack
  102.   THEN
  103.     IF DUP TYPE 3 ==                    @ There is object, check if array
  104.     THEN
  105.       DUP 'XY' STO SIZE 1 GET 'N' STO   @ Save Array and Number of points
  106.       CLLCD                             @ Clear screen for progess updates
  107.       LijCAL                            @ Calculate L coefficients
  108.       KCAL                              @ Calculate final K coefficients
  109.     ELSE EMESS                          @ Display error message
  110.     END
  111.     {CST POLY VIEWK Fx}                 @ Restore main variable order
  112.     ORDER                               @ after new variables are created
  113.   ELSE
  114.     EMESS                               @ Display error message
  115.   END
  116. \>>
  117. CST
  118. {                                       @ Custom Menu for Polyfit program
  119.   {"POLY" POLY}                         @ Main program to find coefficients
  120.   {"VIEW" VIEWK}                        @ View polynomial coefficients
  121.   {"Fx" Fx}                             @ Given X (on stack) return f(X)
  122.   {}                                    @ Nothing
  123.   {}                                    @ Nothing
  124.   { "X-Y" XY}                           @ Recall input array to stack for editing
  125. }
  126. Cab
  127. \<< @ Generate terms to sum for C(a)(b) @
  128.   IF DUP2 ==
  129.   THEN DROP2 1                          @ If a=b, the Cab=1
  130.   ELSE
  131.     0 1 \-> a b SUM Index
  132.     \<<
  133.       { 1 }                             @ Initial list
  134.  
  135.       DO  @ For all possible terms @
  136.         WHILE @ Build list up to a-b terms @
  137.           Index a b - <                 @ Until we hit last term
  138.         REPEAT
  139.           DUP Index GET 1 + 1 \->LIST +  @ Add next term to list
  140.           Index 1 + 'Index' STO
  141.         END
  142.  
  143.         DO  @ Increment last terms until limit @
  144.           FETCH                         @ Get X values and multiply
  145.           SUM + 'SUM' STO               @ Add to sum and save
  146.           DUP Index GET 1 + Index SWAP
  147.           DUP 4 ROLLD PUT               @ Increment last term and save
  148.         UNTIL SWAP b Index + >          @ Until we go over b+Index limit
  149.         END
  150.  
  151.         IF Index 1 >  @ Increment previous terms @
  152.         THEN                            @ If possible
  153.           DO
  154.             Index 1 - 'Index' STO       @ Decrement index
  155.             1 Index SUB                 @ Shorten list
  156.             DUP Index GET 1 + Index SWAP
  157.             DUP 4 ROLLD PUT             @ Increment this term and save
  158.           UNTIL
  159.             SWAP b Index + \<=          @ This term at limit
  160.             Index 1 == OR               @ or this is last term
  161.           END
  162.         END
  163.       UNTIL
  164.         DUP Index GET b Index + >
  165.         Index 1 == AND
  166.       END
  167.       DROP                              @ Remove last list from stack
  168.       SUM
  169.       -1 a b - ^ *                      @ Fix sign of product
  170.     \>>
  171.   END                                   @ If a=b
  172. \>>
  173. EMESS
  174. \<< @ Display error message if no stack value, or value is not an array @
  175.   CLLCD
  176.   "Input array not found." 1 DISP
  177.   "Use Matrix Writer to " 3 DISP
  178.   "enter your X Y values" 4 DISP
  179.   "into an array on the" 5 DISP
  180.   "stack.  Then start" 6 DISP
  181.   "POLY again." 7 DISP
  182.   7 FREEZE
  183. \>>
  184. EQ
  185. Y.EQ                                    @ For PLOTR to plot f(x)
  186. FETCH
  187. \<< @ Use Index list on stack to fetch X values and multiply @
  188.   DUP SIZE 1 \-> lst n product          @ Save term list, size, and product
  189.   \<<
  190.     XY
  191.     1 n
  192.     FOR i
  193.       DUP lst i GET 1 XYindex GET       @ Get Xi term
  194.       product * 'product' STO           @ Multiply and save result
  195.     NEXT
  196.     DROP                                @ Drop XY array
  197.     lst product                         @ Restore term list and product
  198.   \>>
  199. \>>
  200. Fx
  201. \<<  @ Calculate F(x) using K coefficients and x value from stack @
  202.   K N GET                               @ First coefficient
  203.   N 1 - 1
  204.   FOR i                                 @ For i = N-1 to 1
  205.     OVER *                              @ x times
  206.     K i GET +                           @ Add in next coefficient
  207.     -1
  208.   STEP
  209.   SWAP DROP                             @ Remove x value
  210. \>>
  211. KCAL
  212. \<< @ Calculate K coefficients (f(x) = Kn*x^n-1 + ... K2*x + K1) @
  213.   1 N
  214.   START                                 @ Create K array with N zeroes
  215.     0
  216.   NEXT
  217.   N \->ARRY 'K' STO                     @ Save K array
  218.  
  219.   1 N
  220.   FOR i                                 @ i=1 to N
  221.     "DOING K" STD i \->STR + 1 DISP     @ Display Ki value
  222.     0                                   @ Zero sum
  223.     i 1 - N 1 -
  224.     FOR j                               @ j=i-1 to N-1
  225.       @ Ki = Ki + Lj1 * C(j)(i-1) @
  226.       L j 1 Lindex GET                  @ Get L term from array
  227.       j i 1 - Cab                       @ Get Cab coefficient
  228.       * +                               @ Sum to Ki
  229.     NEXT
  230.     K i 3 ROLL PUT 'K' STO              @ Add K value to array
  231.     "K" i \->STR + "=" + K i GET \->STR + 3 DISP
  232.   NEXT
  233. \>>
  234. LijCAL
  235. @ Calculate triangular table of L values @
  236. \<<
  237.   "DOING L:" 1 DISP
  238.   1 TMAX                                @ Create L values array
  239.   START                                 @ With TMAX zeroes
  240.     0
  241.   NEXT
  242.   TMAX \->ARRY                          @ L array initialized
  243.   1 N                                   @ Set Lj,1 = Yj
  244.   FOR j                                 @ For i=0, j = 1 to N
  245.                                         @ L array already on stack
  246.     j                                   @ L index value to place Y value
  247.     XY j 2 * GET                        @ Y value for L array
  248.     PUT                                 @ Y value now in L array
  249.   NEXT
  250.                                         @ Initialized L array left on stack
  251.   1 N 1 -
  252.   FOR i                                 @ For i = 1 to N-1
  253.     1 N i -
  254.     FOR j                               @ For j = 1 to N-i
  255.       DUP DUP i 1 - j 1 + Lindex GET    @ Get L i-1,j+1 value
  256.       SWAP i 1 - j Lindex GET -         @ Get L i-1,j value and subtract
  257.       XY DUP i j + 1 XYindex GET        @ Get X i+j value
  258.       SWAP j 1 XYindex GET -            @ Get X j value and subtract
  259.       / i j Lindex SWAP PUT             @ Save new L i,j into array
  260.     NEXT
  261.   NEXT
  262.   'L' STO                               @ Save final array
  263. \>>
  264. Lindex
  265. @ Return index into L array of i,j element @
  266. \<<
  267.   \-> i j                               @ Save index values
  268.   \<<
  269.     i 1 - N i 2 / - * N + j +           @ index=(i-1)(N-i/2)+j+N
  270.   \>>
  271. \>>
  272. PPAR
  273. {
  274.   (-6.5,-3.1)                           @ X range
  275.   (6.5,3.2)                             @ Y range
  276.   X                                     @ Independent Variable
  277.   0                                     @ Resolution (pixel in each column)
  278.   (0,0)                                 @ Axes intersection
  279.   FUNCTION                              @ Function type
  280.   Y                                     @ Dependent Variable
  281. }
  282. TMAX
  283. @ Maximum Number of elements in the L triangular array @
  284. \<<
  285.   N DUP 1 + * 2 /                       @ TMAX = N(N+1)/2
  286. \>>
  287. VIEWK
  288. \<< @ Display the K coefficients of the resulting polynomial expression @
  289.   STD CLLCD "Hit VIEW to cont..." 1 DISP
  290.   N 1
  291.   FOR i                                 @ For each coefficient
  292.     "K" i \->STR + "=" +
  293.     K i GET \->STR + "*x^" + i 1 -
  294.     \->STR + 3 DISP 0 WAIT DROP
  295.     -1
  296.   STEP
  297.   CLLCD                                 @ Clear display to let user know
  298.                                         @ the program is still working
  299.   KILL                                  @ Get rid of HALT annunciator
  300. \>>
  301. XYindex
  302. @ Return index into XY array of i,j element @
  303. \<<
  304.   \-> i j                               @ Save index values
  305.   \<<
  306.     i 1 - 2 * j +                       @ index=2(i-1)+j
  307.   \>>
  308. \>>
  309. Y.EQ
  310. \<< @ Fx function requires X value from stack, not compatible with PLOTR. @
  311.   @ This program takes 'X' from PLOTR function, calls Fx, and @
  312.   @ returns with f(x) value to satisfy PLOTR requirements. @
  313.   X Fx
  314. \>>
  315. END_RPL
  316.  
  317.